package com.somsoft.bzfk;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

import com.somsoft.bzfk.common.GameInfo;
import com.somsoft.bzfk.common.Map;
import com.somsoft.bzfk.common.Utils;
import com.somsoft.bzfk.common.WaitingBlock;
import com.somsoft.bzfk.db.Service;

public class GameView extends SurfaceView implements Runnable,SurfaceHolder.Callback{

	
	private Thread currentThread;
	public SurfaceHolder surfaceHolder;//引用holder
	GameActivity mainActivity;
	Bitmap background,wall;
	Bitmap[] fkPic = new Bitmap[8];
	
	Map map ;
	WaitingBlock currFk; //左下角的方块
	GameInfo gi;
	
	public GameView(GameActivity mainActivity,GameInfo gi) {
		super(mainActivity);
		this.mainActivity = mainActivity;
		this.gi = gi;
		initPic();
		surfaceHolder = this.getHolder();
		surfaceHolder.addCallback(this);
		/*** 初始化线程并开启线程 ***/
		currentThread = new Thread(this);
		currentThread.start();
	}
	
	private void initPic(){
		String path = "pics/";
		background = Utils.getImageFromAssetsFile(this,path + "background"+gi.getPpi()+".png");
		wall = Utils.getImageFromAssetsFile(this,path + "fk0.png");
		for (int i = 0; i < fkPic.length; i++) {
			fkPic[i] = Utils.getImageFromAssetsFile(this, path + "fk" + (i + 1) + ".png");
		}
		map = parseMap(this, gi.getLevel());
		getBlock();
	}

	private void getBlock(){
		currFk = Utils.randBlock();
		countXY();
	}
	
	private void countXY(){
		// 计算左下角方块的开始坐标
		int startX = ((gi.getGridUnit()*3+20) - currFk.getWidth() * gi.getGridUnit()) / 2;
		int startY = gi.getHeight() - (gi.getGridUnit()*3+20) + ((gi.getGridUnit()*3+20) - currFk.getHeight() * gi.getGridUnit()) / 2;
		currFk.setStartX(startX);
		currFk.setStartY(startY);
	}
	
	protected void doDraw(Canvas canvas) throws Exception{
		super.onDraw(canvas);
		canvas.drawColor(Color.BLACK);		//清屏
		
		Paint paint = new Paint();		
		paint.setAntiAlias(true);   //抗锯齿
		//画背景
		canvas.drawBitmap(background, 0,0, paint); 
		//画地图
		drawMap(canvas,paint);
		//画左下角方块
		drawWaitingBlock(canvas,paint);
	}
	
	
	int downX = -1, downY = -1;
	int tmpStartX = -1, tmpStartY = -1;
	
	public boolean onTouchEvent(MotionEvent event) {

		int action = event.getAction();
		int nowX = (int) event.getX();
		int nowY = (int) event.getY();

		if (action == MotionEvent.ACTION_DOWN && downX == -1) {
			downX = (int) event.getX();
			downY = (int) event.getY();
			tmpStartX = currFk.getStartX();
			tmpStartY = currFk.getStartY();
		} else if (action == MotionEvent.ACTION_UP) {
			//判断点击按钮
			int icon = getTouchIcon(downX, downY);
			if(icon==2){//旋转
				currFk = Utils.getNextBlock(currFk.getX(), currFk.getY(),currFk.getColor());
				countXY();
			}else if(icon==3){//重新获取方块
				getBlock();
			}else if(icon==4){//重新开始
				restart();
			}else{
				boolean flag = false;
				int newStartX = tmpStartX + nowX - downX;
				int newStartY = tmpStartY + nowY - downY;
				if (newStartX >= gi.getMapStartX() && (newStartX + currFk.getWidth() * gi.getGridUnit()) <= gi.getMapEndX()) {
					if (newStartY >= gi.getMapStartY() && (newStartY + currFk.getHeight() * gi.getGridUnit()) <= gi.getMapEndY()) {
						// 判断当前位置是否能放下方块
						flag = isPutdown(map, currFk, currFk.getStartX(), currFk.getStartY());
					}
				}
				if (flag) {
					putdown(map, currFk, currFk.getStartX(), currFk.getStartY());
					//判断是否过关
					boolean ispass = isPass();
					if(ispass){
						//保存当前应该进行的关卡，并加载下一关地图
						Service s = new Service(mainActivity);
						gi.setLevel(gi.getLevel()+1);
						if(gi.getLevel()<=20){
							s.save(gi.getLevel());
							map = parseMap(this, gi.getLevel());
							getBlock();
						}
					}else{
						getBlock();
					}
				} else {
					currFk.setStartX(tmpStartX);
					currFk.setStartY(tmpStartY);
				}
			}
			downX = -1;
			downY = -1;
		} else if (action == MotionEvent.ACTION_MOVE) {
			int w1 = gi.getGridUnit() * 3 + 20;
			int y0 = gi.getHeight() - w1;
			boolean iscollsion = isCollsion(0, y0, w1, w1, downX, downY);
			if(iscollsion){
				currFk.setStartX(tmpStartX + nowX - downX);
				currFk.setStartY(tmpStartY + nowY - downY);
			}
		}
		return true;
	}
	
	private boolean isPass(){
		for (int i = 0; i < map.getBlocks().length; i++) {
			for (int j = 0; j < map.getBlocks()[i].length; j++) {
				int fk = map.getBlocks()[i][j];
				 if (fk == 9) {
					return false;
				} 
			}
		}
		return true;
	}
	
	//重新开始
	private void restart(){
		for (int i = 0; i < map.getBlocks().length; i++) {
			for (int j = 0; j < map.getBlocks()[i].length; j++) {
				int fk = map.getBlocks()[i][j];
				 if (fk >= 1 && fk <= 8) {
					 map.getBlocks()[i][j] = 9;
				} 
			}
		}
	}
	
	private int getTouchIcon(int dx,int dy){
//		boolean f1 = isCollsion(0, gi.getHeight()-gi.getIconSize1(), gi.getIconSize1(), gi.getIconSize1(), dx, dy);
		boolean f2 = isCollsion(gi.getIconSize1(), gi.getHeight()-gi.getIconSize2(), gi.getIconSize2(), gi.getIconSize2(), dx, dy);
		boolean f3 = isCollsion(gi.getIconSize1()+gi.getIconSize2(), gi.getHeight()-gi.getIconSize2(), gi.getIconSize2(), gi.getIconSize2(), dx, dy);
		boolean f4 = isCollsion(gi.getIconSize1()+gi.getIconSize2()*2, gi.getHeight()-gi.getIconSize2(), gi.getIconSize2(), gi.getIconSize2(), dx, dy);
		if(f2){
			return 2;
		}else if(f3){
			return 3;
		}else if(f4){
			return 4;
		}else{
			return -1;
		}
	}
	
	//画地图
	//-1空，0墙，1-8颜色方块，9可放置区域
	private void drawMap(Canvas canvas, Paint paint) {
		Matrix m1 = new Matrix();
		Matrix m2 = new Matrix();
		m2.setScale(gi.getGridUnit()/100f, gi.getGridUnit()/100f);
		Matrix m3 = new Matrix();
		
		
		for (int i = 0; i < map.getBlocks().length; i++) {
			for (int j = 0; j < map.getBlocks()[i].length; j++) {
				int fk = map.getBlocks()[i][j];
				if (fk == 0) {
					m1.setTranslate(j*gi.getGridUnit()+gi.getMapStartX(), i*gi.getGridUnit()+gi.getMapStartY());
					m3.setConcat(m1, m2);
					canvas.drawBitmap(wall, m3, paint);
				}  else if (fk >= 1 && fk <= 8) {
					m1.setTranslate(j*gi.getGridUnit()+gi.getMapStartX(), i*gi.getGridUnit()+gi.getMapStartY());
					m3.setConcat(m1, m2);
					canvas.drawBitmap(fkPic[fk - 1], m3, paint);
				} else if (fk == 9) {
					paint.setColor(Color.WHITE);
					paint.setStyle(Paint.Style.STROKE);
					canvas.drawRect(j * gi.getGridUnit()+gi.getMapStartX(), i * gi.getGridUnit()+gi.getMapStartY(), 
							j * gi.getGridUnit()+gi.getMapStartX()+gi.getGridUnit(), i * gi.getGridUnit()+gi.getMapStartY()+gi.getGridUnit(), paint);
				}
			}
		}
	}
	
	//画左下角方块
	private void drawWaitingBlock(Canvas canvas, Paint paint) {
		Matrix m1 = new Matrix();
		Matrix m2 = new Matrix();
		m2.setScale(gi.getGridUnit()/100f, gi.getGridUnit()/100f);
		Matrix m3 = new Matrix();
		
		for (int i = 0; i < currFk.getFks().length; i++) {
			for (int j = 0; j < currFk.getFks()[i].length; j++) {
				int fk = currFk.getFks()[i][j];
				if (fk >= 1 && fk <= 8) {
					int tmpX = j * gi.getGridUnit() + currFk.getStartX();
					int tmpY = i * gi.getGridUnit() + currFk.getStartY();
					m1.setTranslate(tmpX, tmpY);
					m3.setConcat(m1, m2);
					canvas.drawBitmap(fkPic[fk - 1], m3, paint);
				}
			}
		}
	}
	
	//判断当前方块是否能落下，x,y为当前方块起点坐标
	private boolean isPutdown(Map map, WaitingBlock currFk, int currStartX, int currStartY) {
		int[][] mapBlocks = map.getBlocks();
		int tmpX = (int)(currStartX-gi.getMapStartX()) / gi.getGridUnit();
		int tmpY = currStartY  / gi.getGridUnit();
		int[][] currBlocks = currFk.getFks();
		for (int i = 0; i < currBlocks.length; i++) {
			for (int j = 0; j < currBlocks[i].length; j++) {
				int currB = currBlocks[i][j];
				if (currB >= 1 && currB <= 8) {
					int mapB = mapBlocks[tmpY + i][tmpX + j];
					if (mapB != 9) {
						return false;
					}
				}
			}
		}
		return true;
	}
	
	//放下方块
	private void putdown(Map map, WaitingBlock currFk, int currStartX, int currStartY) {
		int[][] mapBlocks = map.getBlocks();
		int tmpX = currStartX / gi.getGridUnit();
		int tmpY = currStartY / gi.getGridUnit();
		int[][] currBlocks = currFk.getFks();
		for (int i = 0; i < currBlocks.length; i++) {
			for (int j = 0; j < currBlocks[i].length; j++) {
				int currB = currBlocks[i][j];
				if (currB >= 1 && currB <= 8) {
					mapBlocks[tmpY + i][tmpX + j] = currB;
				}
			}
		}
	}
	
	//解析地图数据
	public Map parseMap(View v, int level) {
		String filePath = "maps/lv" + level + ".som";
		JSONArray array = Utils.getMapFromAssetsFile(v, filePath);
		int[][] fks = new int[18][13];
		for (int i = 0; i < array.length(); i++) {
			try {
				JSONObject obj = array.getJSONObject(i);
				fks[obj.getInt("y")][obj.getInt("x")] = obj.getInt("type");
			} catch (JSONException e) {
				Log.e("解析地图出错", "解析地图出错", e);
			}
		}
		Map map = new Map(10, 100, fks);
		return map;
	}
	
	@Override
	public void run() {
		Canvas canvas = null; // 创建一个Canvas对象
		while (currentThread != null) {
			try {
				canvas = surfaceHolder.lockCanvas(null); // 为画布加锁
				synchronized (surfaceHolder) {
					if (canvas != null) {
						doDraw(canvas); // 重新绘制屏幕
					}
				}
			} catch (Exception e) {
				e.printStackTrace(); // 捕获异常并打印
			} finally {
				if (canvas != null) {// 释放画布并将其传回
					surfaceHolder.unlockCanvasAndPost(canvas);
				}
			}
			try {
				Thread.sleep(100); // 休眠一段时间
			} catch (Exception e) {
				e.printStackTrace(); // 捕获异常并打印
			}
		}

	}
	
	
	/**
	 * 判断矩形是否与该点碰撞
	 * @param recX
	 * @param recY
	 * @param recWidth
	 * @param recHeight
	 * @param pX
	 * @param pY
	 * @return
	 */
	public boolean isCollsion(int recX, int recY, int recWidth, int recHeight, int pX,int pY){
		if(pX >= recX && pX <= recX+recWidth && pY >= recY && pY <= recY+recHeight){
			return true;
		}else{
			return false;
		}
	}
	
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
		
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		currentThread = null;// 摧毁线程
	}

}
